using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;

namespace RideMe.Presentation.Controls
{
    internal static class IconExtractor
    {
        private enum Shgfi
        {
            Icon = 0x000000100,     // get icon
            DiplayName = 0x000000200,     // get display name
            TypeName = 0x000000400,     // get type name
            Attributes = 0x000000800,     // get attributes
            IconLocation = 0x000001000,     // get icon location
            ExeType = 0x000002000,     // return exe type
            SysIconIndex = 0x000004000,     // get system icon index
            LinkOverlay = 0x000008000,     // put a link overlay on icon
            Selected = 0x000010000,     // show icon in selected state
            AttrSpecified = 0x000020000,     // get only specified attributes
            LargeIcon = 0x000000000,     // get large icon
            SmallIcon = 0x000000001,     // get small icon
            OpenIcon = 0x000000002,     // get open icon
            ShellIconSize = 0x000000004,     // get shell size icon
            Pidl = 0x000000008,     // pszPath is a pidl
            UseFileAttributes = 0x000000010     // use passed dwFileAttribute
        }


        [DllImport("Shell32.dll")]
        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes,
            out SHFILEINFO psfi, uint cbfileInfo, Shgfi uFlags);

        /// <summary>
        /// Gets the icon.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="selected">if set to <c>true</c> [selected].</param>
        /// <returns></returns>
        public static Bitmap GetIcon(string path, bool selected)
        {
            SHFILEINFO info = new SHFILEINFO(true);
            int cbFileInfo = Marshal.SizeOf(info);
            Shgfi flags;
            if (!selected)
            {
                flags = Shgfi.Icon | Shgfi.SmallIcon;
            }
            else
            {
                flags = Shgfi.Icon | Shgfi.SmallIcon | Shgfi.OpenIcon;
            }


            SHGetFileInfo(path, 256, out info, (uint)cbFileInfo, flags);

            if (info.hIcon.ToInt32() == 0)
            {
                throw new ArgumentException();
            }

            return Bitmap.FromHicon(info.hIcon);

        }

        [StructLayout(LayoutKind.Sequential)]
        private struct SHFILEINFO
        {
            public SHFILEINFO(bool b)
            {
                hIcon = IntPtr.Zero; iIcon = 0; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
            }
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
            public string szTypeName;
        }

    }
}
